<html>
<head>
<title>NES ASM - Day 19</title>
</head>
<body bgcolor="lavender">
<h1 align="center" style="color: LightCoral; width: 100%; filter:shadow()">Day 19 - Easy Large Loads</h1>
<pre>


</pre>
<h2 align="center" style="color: LightCoral;"><b>What?</b></h2>
<p style="color: green;"><pre><b>
	Today, we will use a new loading loop that utilizes <i>indirect addressing</i>
to load a lot of data at a time. The data we will load will be the Zelda title
screen, and yes, today will include all of the code. I've included the 3 necessary
data files in <a href="nesasm.zip">nesasm.zip</a>. Please redownload it, I could
have sworn that I already had them in there... sorry for any inconveniece.

<h2 align="center" style="color: LightCoral;"><b>Indirect Addressing?</b></h2>
	Yep, indirect addressing (which is hard for me to type for some reason...)
is simply getting an address from the contents of another address, so say we wanted
to get a value from an address contained at $0010-$0011 (16-bit address, remember
that). 

	But first a little review (I hope), vocab lesson #whatever:
	Take the address $8000, $00 is the high byte and $80 is the low byte, got it?
	(I might have that backwards, I have bronchitis at the moment...)

	The low byte would be in $10 and the high byte in $11 (note that I use two
digits only, because the first 2 in the address are zero). So assuming the address
that we really want to load from is $82C5 which is at $10-$11, to load the byte
at $82C5 into the A register, we would do:

	lda [$10]

this can also be indexed, like so:

	lda [$10], y

what this would do is take the address $82C5, add the contents of Y to that address
(the <i>address</i> not the contents), and get byte at the resulting address.

I hope you understood all that, because it's just going to get more confusing.
And just a short joke before we continue:

Surgeon General's Warning:
Attempting to understand the ASM Code in the
following sections of this document may cause
the reader to either increase their ASM skills
or drive them to suicidal frustration.

<h3 align="center" style="color: LightCoral;"><b>The Loop</b></h3>
	I think, therefore I am? no. I think therefore I'll give the complete
loop and explain it in pieces. Assume backg is the label of where a bunch of
name table data is included, also assume $2006 is pointing to $2000:

	lda #low(backg)
  	sta $10
  	lda #high(backg)
  	sta $11

	ldx #4  
  	ldy #0
loop:
  	lda [$10],y
  	sta $2007
  	iny
  	bne loop
  	inc $11 
  	dex
  	bne loop

The first piece:
	lda #low(backg)
  	sta $10
  	lda #high(backg)
  	sta $11

low() and high() are builtin instructions for NESASM.exe that take the high and low
bytes of an address, in this case, backg.
Note that $10 and $11 memory addresses are consecutive, it has to be that way, but
they could be any consecutive addresses.

The second:
	ldx #4  
  	ldy #0
loop:
X controls how many chunks of 256 bytes to load in this case, 4. Y must be 0 (zero).

The third:
	lda [$10],y
  	sta $2007
  	iny
  	bne loop
This part loads 256 bytes to $2007 using indirect addressing indexed by Y.
Note that the registers (A,X,Y) wrap around so adding 1 to #$FF will make
the register contain #$00. And that's how this works, because when Y is incremented
to #$00, the loop will be done loading the 256 byte chunk.

The last:
 	inc $11 
  	dex
  	bne loop
This part increments the high byte of the address of the data to the next 256 byte
chunk. It also counts down 1 in the X register which contains the amount of chunks
left, if X is zero, it won't loop and we're done loading everything.

That went better than I expected...
<h3 align="center" style="color: LightCoral;"><b>The Full Code File</b></h3>
Before I give you the full code file (fully commented, of course), make sure
you have those 3 files in your code folder.

;--- CODE START ---;
	.inesmir 1
	.inesmap 0      ; INES header $H!7.
	.ineschr 1
	.inesprg 1

	.bank 1
	.org $FFFA  ; vector table
	.dw 0
	.dw Start
	.dw 0

	.bank 0
	.org $0010
addrLO:	.db 0  ; make "variable"s for our indirect addressing
addrHI: .db 0

	.org $8000
Start:
	
	ldx #0
	lda #$20  ; set the destination address in PPU memory
  	sta $2006  ; should be $2000
  	stx $2006
  	lda #low(backg)   ; put the high and low bytes of the address "backg"
  	sta addrLO        ; into the variables so we can use indirect addressing.
  	lda #high(backg)
  	sta addrHI

	ldx #4  ; number of 256-byte chunks to load
  	ldy #0
loop:
  	lda [addrLO],y
  	sta $2007     ; load 256 bytes
  	iny
  	bne loop
;--------------------
  	inc addrHI  ; increment high byte of address backg to next 256 byte chunk
  	dex        ; one chunk done so X = X - 1.
  	bne loop   ; if X isn't zero, do again
	


	lda #$3F
	sta $2006
	lda #$00    ; point $2006 to the pallete
	sta $2006
	ldx #$00
palload:
	lda tilepal, X     ; use a simple load of 32 bytes.
	inx
	sta $2007
	cpx #32
	bne palload

	jsr turn_screen_on  ; call subroutine to turn on / setup the PPU.

infin:              ; our infinite loop
	jmp infin

turn_screen_on:
	; Setup the PPU
	lda #%00001000
	sta $2000
	lda #%00011110
	sta $2001
	rts

tilepal: .incbin "zelda.pal" ; include the pallete
backg: .incbin "zelda.nam" ; include the name table data

	.bank 2
	.org $0000
	.incbin "zelda.chr"  ; include the picture data in the background part
	;of the CHR-BANK (#2)
;;--- CODE END/ END OF FILE ---;;

I hope you got all that and that it works (I did some modifications from my
testing file).

<h3 align="center" style="color: LightCoral;"><b>This Day In Review</b></h3>

	I thought that was fun. Day 20 could be anything, maybe Attributes,
maybe a lesson on the conditional branches.

	Have fun!,
		- GbaGuy

<center><a href="nesasm.htm">Intro</a> - <a href="day20n.htm">Day 20</a></center>


</b></pre></p>

<br />
<br />

</body>
</html>
